using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Linq;

namespace Tryit.Models
{
    public class CompositionTemplate : INotifyPropertyChanged
    {
        private string _name;
        private string _description;
        private DateTime _createTime;
        private DateTime _updateTime;
        private ObservableCollection<ElementComposition> _elements;
        private bool _isDefault;

        public string Name
        {
            get => _name;
            set => SetProperty(ref _name, value);
        }

        public string Description
        {
            get => _description;
            set => SetProperty(ref _description, value);
        }

        public DateTime CreateTime
        {
            get => _createTime;
            set => SetProperty(ref _createTime, value);
        }

        public DateTime UpdateTime
        {
            get => _updateTime;
            set => SetProperty(ref _updateTime, value);
        }

        public ObservableCollection<ElementComposition> Elements
        {
            get => _elements;
            set => SetProperty(ref _elements, value);
        }

        public bool IsDefault
        {
            get => _isDefault;
            set => SetProperty(ref _isDefault, value);
        }

        public CompositionTemplate()
        {
            Elements = new ObservableCollection<ElementComposition>();
            CreateTime = DateTime.Now;
            UpdateTime = DateTime.Now;
        }

        public CompositionTemplate(string name, string description = "")
        {
            Name = name;
            Description = description;
            Elements = new ObservableCollection<ElementComposition>();
            CreateTime = DateTime.Now;
            UpdateTime = DateTime.Now;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        public void AddElement(ElementComposition element)
        {
            Elements.Add(element);
            UpdateTime = DateTime.Now;
        }

        public void RemoveElement(ElementComposition element)
        {
            Elements.Remove(element);
            UpdateTime = DateTime.Now;
        }

        public void UpdateElement(ElementComposition element)
        {
            var index = Elements.ToList().FindIndex(e => e.Name == element.Name);
            if (index >= 0)
            {
                Elements[index] = element;
                UpdateTime = DateTime.Now;
            }
        }

        public ElementComposition GetElement(string elementName)
        {
            return Elements.FirstOrDefault(e => e.Name == elementName);
        }

        public void ValidateAllElements()
        {
            foreach (var element in Elements)
            {
                element.ValidateStatus();
            }
        }
    }
} 